package com.logistics.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.logistics.entity.SysUser;
import com.logistics.entity.SysRole;
import com.logistics.mapper.SysUserMapper;
import com.logistics.mapper.SysRoleMapper;
import com.logistics.common.TenantContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户服务类
 */
@Service
public class UserService {
    
    @Autowired
    private SysUserMapper userMapper;
    
    @Autowired
    private SysRoleMapper roleMapper;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private RoleHierarchyService roleHierarchyService;
    
    /**
     * 获取当前登录用户
     */
    private SysUser getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.getPrincipal() instanceof Long userId) {
            return userMapper.selectById(userId);
        }
        return null;
    }
    
    /**
     * 分页查询用户列表
     */
    public IPage<SysUser> getUserList(int current, int size, String keyword, Integer status) {
        Long tenantId = TenantContextHolder.getTenantId();
        // 获取当前登录用户，用于基于角色的可见范围控制
        SysUser currentUser = getCurrentUser();
        
        Page<SysUser> page = new Page<>(current, size);
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getTenantId, tenantId);

        // 所有非最高级用户都不应看到上级管理员账号
        if (currentUser != null) {
            String currentRole = currentUser.getRole();
            if ("PLATFORM_ADMIN".equals(currentRole)) {
                // 平台管理员：可见所有（按租户过滤）
            } else if ("SUPER_ADMIN".equals(currentRole)) {
                // 租户超级管理员：看不到平台管理员（理论上不在本租户内，这里做保护）
                wrapper.ne(SysUser::getRole, "PLATFORM_ADMIN");
            } else if ("SITE_ADMIN".equals(currentRole)) {
                // 站点管理员：看不到超级管理员/平台管理员
                wrapper.ne(SysUser::getRole, "SUPER_ADMIN")
                       .ne(SysUser::getRole, "PLATFORM_ADMIN");
            } else {
                // 其他业务角色：看不到任何管理员级别角色
                wrapper.ne(SysUser::getRole, "PLATFORM_ADMIN")
                       .ne(SysUser::getRole, "SUPER_ADMIN")
                       .ne(SysUser::getRole, "SITE_ADMIN");
            }
        }
        
        if (keyword != null && !keyword.isEmpty()) {
            wrapper.and(w -> w.like(SysUser::getUsername, keyword)
                            .or()
                            .like(SysUser::getRealName, keyword)
                            .or()
                            .like(SysUser::getPhone, keyword));
        }
        
        if (status != null) {
            wrapper.eq(SysUser::getStatus, status);
        }
        
        wrapper.orderByDesc(SysUser::getCreateTime);
        
        IPage<SysUser> result = userMapper.selectPage(page, wrapper);
        
        // 填充角色名称（优先使用roleId查询角色表）
        result.getRecords().forEach(user -> {
            if (user.getRoleId() != null) {
                // 优先从角色表查询真实的角色名称
                SysRole role = roleMapper.selectById(user.getRoleId());
                if (role != null) {
                    user.setRoleName(role.getRoleName());
                }
            } else if (user.getRole() != null && !user.getRole().isEmpty()) {
                // 兼容没有 roleId 的情况，使用 role 字段
                user.setRoleName(roleHierarchyService.getRoleDisplayName(user.getRole()));
            }
        });
        
        return result;
    }
    
    /**
     * 根据ID获取用户信息
     */
    public SysUser getUserById(Long id) {
        return userMapper.selectById(id);
    }
    
    /**
     * 创建用户
     */
    @Transactional
    public SysUser createUser(SysUser user) {
        Long tenantId = TenantContextHolder.getTenantId();
        
        // 获取当前登录用户
        SysUser currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("未登录");
        }
        
        // 计算目标角色：优先使用传入的 role，其次使用 roleId 映射得到的 roleCode
        String targetRole = user.getRole();
        if ((targetRole == null || targetRole.isEmpty()) && user.getRoleId() != null) {
            SysRole role = roleMapper.selectById(user.getRoleId());
            if (role != null) {
                targetRole = role.getRoleCode();
            }
        }
        if (targetRole == null || targetRole.isEmpty()) {
            throw new RuntimeException("请指定角色");
        }
        // 检查当前用户是否有权限创建目标角色的用户
        if (!roleHierarchyService.canCreateRole(currentUser.getRole(), targetRole)) {
            throw new RuntimeException("您没有权限创建该角色的用户。当前角色：" + 
                roleHierarchyService.getRoleDisplayName(currentUser.getRole()) + 
                "，目标角色：" + roleHierarchyService.getRoleDisplayName(targetRole));
        }
        
        // 检查用户名是否重复
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getTenantId, tenantId)
               .eq(SysUser::getUsername, user.getUsername());
        
        if (userMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 设置租户ID
        user.setTenantId(tenantId);
        
        // 设置用户角色（若前端未直接传入 role，则根据 roleId 映射的 targetRole 设置）
        if (user.getRole() == null || user.getRole().isEmpty()) {
            user.setRole(targetRole);
        }
        
        // 密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        
        // 如果还在使用 roleId，也需要处理（兼容性）
        if (user.getRoleId() != null) {
            SysRole role = roleMapper.selectById(user.getRoleId());
            if (role != null) {
                user.setRole(role.getRoleCode());
            }
        }
        
        userMapper.insert(user);
        
        return user;
    }
    
    /**
     * 更新用户
     */
    @Transactional
    public void updateUser(SysUser user) {
        // 获取当前登录用户
        SysUser currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("未登录");
        }
        
        // 获取原用户信息
        SysUser existingUser = userMapper.selectById(user.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查当前用户是否有权限管理目标用户
        if (!roleHierarchyService.canManage(currentUser.getRole(), existingUser.getRole())) {
            throw new RuntimeException("您没有权限管理该用户。当前角色：" + 
                roleHierarchyService.getRoleDisplayName(currentUser.getRole()) + 
                "，目标用户角色：" + roleHierarchyService.getRoleDisplayName(existingUser.getRole()));
        }
        
        // 如果要修改角色
        if (user.getRole() != null && !user.getRole().equals(existingUser.getRole())) {
            // 检查是否有权限创建新角色
            if (!roleHierarchyService.canCreateRole(currentUser.getRole(), user.getRole())) {
                throw new RuntimeException("您没有权限将用户设置为该角色。目标角色：" + 
                    roleHierarchyService.getRoleDisplayName(user.getRole()));
            }
        }
        
        // 检查用户名是否重复（排除自己）
        if (user.getUsername() != null && !user.getUsername().equals(existingUser.getUsername())) {
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUser::getTenantId, existingUser.getTenantId())
                   .eq(SysUser::getUsername, user.getUsername())
                   .ne(SysUser::getId, user.getId());
            
            if (userMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("用户名已存在");
            }
        }
        
        // 如果传入了密码，则加密
        if (user.getPassword() != null && !user.getPassword().isEmpty()) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        } else {
            // 不更新密码
            user.setPassword(null);
        }
        
        // 如果使用 roleId，转换为 role（以数据库 roleCode 为准）
        if (user.getRoleId() != null) {
            SysRole role = roleMapper.selectById(user.getRoleId());
            if (role != null) {
                user.setRole(role.getRoleCode());
            }
        }
        
        userMapper.updateById(user);
    }
    
    /**
     * 删除用户
     */
    @Transactional
    public void deleteUser(Long id) {
        // 获取当前登录用户
        SysUser currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("未登录");
        }
        
        SysUser user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查当前用户是否有权限删除目标用户
        if (!roleHierarchyService.canManage(currentUser.getRole(), user.getRole())) {
            throw new RuntimeException("您没有权限删除该用户。当前角色：" + 
                roleHierarchyService.getRoleDisplayName(currentUser.getRole()) + 
                "，目标用户角色：" + roleHierarchyService.getRoleDisplayName(user.getRole()));
        }
        
        // 不允许删除自己
        if (user.getId().equals(currentUser.getId())) {
            throw new RuntimeException("不能删除自己");
        }
        
        userMapper.deleteById(id);
    }
    
    /**
     * 修改用户状态
     */
    public void updateStatus(Long id, Integer status) {
        // 获取当前登录用户
        SysUser currentUser = getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("未登录");
        }
        
        SysUser user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查当前用户是否有权限管理目标用户
        if (!roleHierarchyService.canManage(currentUser.getRole(), user.getRole())) {
            throw new RuntimeException("您没有权限管理该用户");
        }
        
        // 不允许修改自己的状态
        if (user.getId().equals(currentUser.getId())) {
            throw new RuntimeException("不能修改自己的状态");
        }
        
        SysUser updateUser = new SysUser();
        updateUser.setId(id);
        updateUser.setStatus(status);
        userMapper.updateById(updateUser);
    }
    
    /**
     * 重置用户密码
     */
    public void resetPassword(Long id, String newPassword) {
        SysUser user = new SysUser();
        user.setId(id);
        user.setPassword(passwordEncoder.encode(newPassword));
        userMapper.updateById(user);
    }
    
    /**
     * 获取当前用户可创建的角色列表
     */
    public com.logistics.common.Result<java.util.Map<String, Object>> getCreatableRoles() {
        SysUser currentUser = getCurrentUser();
        if (currentUser == null) {
            return com.logistics.common.Result.error("未登录");
        }
        
        java.util.List<String> roles = roleHierarchyService.getCreatableRoles(currentUser.getRole());
        
        // 转换为带显示名称的列表
        java.util.List<java.util.Map<String, String>> roleList = new java.util.ArrayList<>();
        for (String role : roles) {
            java.util.Map<String, String> roleInfo = new java.util.HashMap<>();
            roleInfo.put("code", role);
            roleInfo.put("name", roleHierarchyService.getRoleDisplayName(role));
            roleInfo.put("level", String.valueOf(roleHierarchyService.getRoleLevel(role)));
            roleList.add(roleInfo);
        }
        
        java.util.Map<String, Object> result = new java.util.HashMap<>();
        result.put("currentRole", currentUser.getRole());
        result.put("currentRoleName", roleHierarchyService.getRoleDisplayName(currentUser.getRole()));
        result.put("creatableRoles", roleList);
        
        return com.logistics.common.Result.success(result);
    }
    
    /**
     * 获取所有具有开票员角色的用户（用于订单筛选）
     */
    public java.util.List<SysUser> getInvoicers() {
        Long tenantId = TenantContextHolder.getTenantId();
        
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getTenantId, tenantId)
               .eq(SysUser::getStatus, 1); // 只获取启用状态的用户
        
        // 获取所有用户，然后筛选出具有开票员角色的用户
        java.util.List<SysUser> allUsers = userMapper.selectList(wrapper);
        
        // 筛选出具有开票员角色的用户
        // 由于开票员角色可能通过roleId或role字段表示，需要同时检查两种情况
        return allUsers.stream()
                .filter(user -> {
                    // 检查role字段是否为开票员角色
                    if ("INVOICER".equals(user.getRole())) {
                        return true;
                    }
                    // 检查roleId对应的role_code是否为开票员角色
                    if (user.getRoleId() != null) {
                        SysRole role = roleMapper.selectById(user.getRoleId());
                        return role != null && "INVOICER".equals(role.getRoleCode());
                    }
                    return false;
                })
                .collect(java.util.stream.Collectors.toList());
    }
}

